package com.fastloan.mgt.application.base.controller;

import com.fastloan.common.model.CheckResult;
import com.fastloan.mgt.application.base.enums.ApplicationStatusEnum;
import com.fastloan.mgt.application.base.model.Application;
import com.fastloan.mgt.application.base.model.ApplicationIPC;
import com.fastloan.mgt.application.base.model.ApplicationValue;
import com.fastloan.mgt.application.base.model.ApplicationVo;
import com.fastloan.mgt.application.base.service.ApplicationIPCService;
import com.fastloan.mgt.application.base.service.ApplicationService;
import com.fastloan.mgt.application.download.DownloadFileToZip;
import com.fastloan.mgt.customer.model.CustomerAmount;
import com.fastloan.mgt.customer.service.CustomerAmountService;
import com.fastloan.mgt.customer.service.ZyCustomerService;
import com.fastloan.mgt.model.service.ModelCalculateService;
import com.fastloan.mgt.three.service.ZyApplicationThreeModelService;
import com.fastloan.safe.core.param.RoleTypeEnum;
import com.fastloan.safe.core.util.ManagerKit;
import com.kawins.base.baseabs.BaseController;
import com.kawins.result.ResultEnum;
import com.kawins.result.ResultTo;
import com.kawins.spring.valid.core.BeanValid;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;

import static com.fastloan.common.model.CheckResultEnum.CUSTOMER_INFO_ALREADY_CREDIT;
import static com.fastloan.common.model.CheckResultEnum.LINE_CREDIT_INSUFFICIENT;
import static com.fastloan.mgt.application.base.enums.ApplicationStatusEnum.PRELIMINARY_CREDIT;
import static com.fastloan.mgt.customer.enums.CustomerAmountEnum.LOSE_EFFICACY;
import static com.fastloan.mgt.customer.enums.CustomerAmountEnum.NORMALS;
import static com.fastloan.mgt.model.service.impl.ModelCalculateServiceImpl.PASS;

/**
 * @author yanwe
 * createTime 2017-11-2017/11/8 13:45
 */
@RestController
@RequestMapping("/api/application")
public class ApplicationController extends BaseController<Application> {

    @Autowired
    private ApplicationIPCService applicationIPCService;

    @Autowired
    private ApplicationService applicationService;

    @Autowired
    private ModelCalculateService modelCalculateService;

    @Autowired
    private ZyApplicationThreeModelService applicationThreeModelService;

    @Autowired
    private DownloadFileToZip downloadUtil;

    @Autowired
    private ZyCustomerService customerService;


    @Autowired
    private CustomerAmountService customerAmountService;

    /**
     * 客户进件分页
     *
     * @return 分页
     */
    @RequestMapping("/customer/pageList")
    public ResultTo customerApplicationPageList() {
        Map<String, Object> map = new HashMap<>();
        map.put("customerId", ManagerKit.getCustomerId());
        return dataPage("selectApplicationVoList", map);
    }


    /**
     * 客户经理进件分页
     *
     * @return 分页
     */
    @RequestMapping("/pageList")
    public ResultTo customerManagerApplicationPageList() {
        Map<String, Object> map = new HashMap<>();
        if (ManagerKit.getRole().getIndexType().equals(RoleTypeEnum.MANAGER.getCode())) {
            map.put("customerManagerId", ManagerKit.getUserId());
        }
        return dataPage("selectApplicationVoList", map);
    }

    /**
     * 提交进件
     *
     * @param applicationVo 进件
     * @return 结果
     */
    @BeanValid
    @RequestMapping("/submit")
    public ResultTo submitApplication(@Valid ApplicationVo applicationVo, BindingResult bindingResult) {
        applicationVo.setCustomerId(ManagerKit.getCustomerId());
        CheckResult checkResult
                = customerAmountService.verifyApplyAmount(applicationVo.getCustomerId(), applicationVo.getProductId(), applicationVo.getApplyAmount());
        if (!checkResult.isCheckResult()) {
            return new ResultTo(ResultEnum.OPERATION_FAILED, checkResult.getCheckMsg());
        }
        ResultTo resultTo = applicationService.submitApplication(applicationVo);
        String creditApplicationId = customerService.queryCreditApplicationIdByCustomer(resultTo.get("applicationId").toString());
        if (!StringUtils.isBlank(creditApplicationId)) {
            customerAmountService.changeCreditAmount(creditApplicationId, applicationVo.getApplyAmount());
        }
        return resultTo;
    }

    /**
     * 提交预授信进件
     *
     * @param applicationVo 进件
     * @return 结果
     */
    @BeanValid
    @RequestMapping("/submitCredit")
    public ResultTo submitCreditApplication(@Valid ApplicationVo applicationVo, BindingResult bindingResult) {
        Integer integer = customerAmountService.queryIfCredit(ManagerKit.getCustomerId());
        //已存在预授信信息
        if (integer != null && integer > 0) {
            return new ResultTo(ResultEnum.OPERATION_FAILED, CUSTOMER_INFO_ALREADY_CREDIT.getMsg());
        }
        ResultTo resultTo = applicationService.submitApplication(applicationVo);
        Object applicationId = resultTo.get("applicationId");
        CustomerAmount customerAmount = new CustomerAmount();
        customerAmount.setCustomerId(ManagerKit.getCustomerId());
        customerAmount.setProductId(applicationVo.getProductId());
        customerAmount.setCreditAmount(BigDecimal.valueOf(RandomUtils.nextInt(10000, 1000000)));
        customerAmount.setOriginalAmount(BigDecimal.valueOf(RandomUtils.nextInt(10000, 1000000)));
        customerAmount.setStatus(0);
        customerAmount.setCreateTime(new Date());
        customerAmount.setApplicationId(applicationId.toString());
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, 6);
        customerAmount.setDeadLine(cal.getTime());
        customerAmountService.insert(customerAmount);
        return resultTo;
    }

    /**
     * 补充调查提交
     *
     * @param applicationId 进件ID
     * @return 结果
     */
    @RequestMapping("/submit/survey/{applicationId}")
    public ResultTo submitSurvey(@PathVariable("applicationId") String applicationId) {
        applicationService.endSurvey(applicationId);
        return new ResultTo();
    }

    /**
     * 根据产品获取IPC
     *
     * @param productId 产品ID
     * @param type      IPC类型 0 客户 1 客户经理
     * @return 结果
     */
    @RequestMapping("/ipc/product/{productId}/{type}")
    public ResultTo selectProductIPC(@PathVariable("productId") String productId
            , @PathVariable("type") Integer type) {
        return new ResultTo().setData(applicationIPCService.selectProductIPC(productId, type
                , ManagerKit.getCustomerId()));
    }

    /**
     * 获取进件详情
     *
     * @param applicationId 进件ID
     * @return 结果
     */
    @GetMapping("/{applicationId}")
    public ResultTo selectApplicationVo(@PathVariable("applicationId") String applicationId) {
        return new ResultTo().setData(applicationService.selectApplicationVo(applicationId));
    }

    /**
     * 获取进件IPC信息
     *
     * @param applicationId 进件ID
     * @return IPC
     */
    @RequestMapping("/ipc/{applicationId}")
    public ResultTo selectManagerIPC(@PathVariable("applicationId") String applicationId) {
        Map<String, Object> map = new HashMap<>();
        ApplicationVo applicationVo = applicationService.selectApplicationVo(applicationId);
        List<ApplicationIPC> applicationIPC = applicationIPCService.selectApplicationIPC(applicationId);
        String creditApplicationId = customerService.queryCreditApplicationIdByCustomer(applicationId);
        if (!StringUtils.isBlank(creditApplicationId)) {
            List<ApplicationIPC> creditApplicationIPC = applicationIPCService.selectApplicationIPC(creditApplicationId);
            map.put("creditApplicationIPC", creditApplicationIPC);
        }
        map.put("applicationInfo", applicationVo);
        map.put("applicationIPC", applicationIPC);
        return new ResultTo().setData("data", map);
    }

    /**
     * 更新IPC
     *
     * @param applicationValue IPC信息
     * @param remark           备注
     * @return 结果
     */
    @RequestMapping("/ipc/update")
    public ResultTo ipcUpdate(ApplicationValue applicationValue
            , @RequestParam(value = "remark", required = false) String remark) {
        CheckResult result = applicationIPCService.updateIPC(applicationValue, remark);
        return result.isCheckResult() ? new ResultTo() : new ResultTo(ResultEnum.OPERATION_FAILED, result.getCheckMsg());
    }

    /**
     * 上传IPC文件
     *
     * @param applicationIpcId ipcId
     * @param files            文件
     * @return 结果
     */
    @PostMapping("/ipc/file")
    public ResultTo uploadIPCFile(@RequestParam("applicationIpcId") String applicationIpcId
            , @RequestPart("files") MultipartFile[] files) {
        return new ResultTo().setData(applicationIPCService.uploadIPCFile(applicationIpcId, files));
    }

    /**
     * 删除IPC文件
     *
     * @param fileId 文件ID
     * @return 结果
     */
    @DeleteMapping("/ipc/file/{applicationIpcId}/{fileId}")
    public ResultTo deleteIPCFile(@PathVariable("applicationIpcId") String applicationIpcId
            , @PathVariable("fileId") String fileId) {
        return new ResultTo().setData(applicationIPCService.deleteFile(applicationIpcId, fileId));
    }

    /**
     * 获取进件模型
     *
     * @param applicationId 进件ID
     * @return 模型
     */
    @GetMapping("/model/{applicationId}")
    public ResultTo model(@PathVariable("applicationId") String applicationId) {
        return new ResultTo()
                .setData("modelResult", modelCalculateService.getLastModelResult(applicationId))
                .setData("baiduModelResult", applicationThreeModelService.getBaiDuModel(applicationId));
    }

    /**
     * 进件状态
     *
     * @return 进件状态
     */
    @GetMapping("/appStatus")
    public ResultTo appStatus() {
        return new ResultTo().setData("appStatus", ApplicationStatusEnum.values());
    }


    /**
     * 进件文件下载
     *
     * @param applicationId
     * @param httpServletRequest
     * @param servletResponse
     */
    @GetMapping("/download/{applicationId}")
    public void download(@PathVariable String applicationId, HttpServletRequest httpServletRequest, HttpServletResponse servletResponse) {
        try {
            downloadUtil.download(applicationId, httpServletRequest, servletResponse);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/pdf/{applicationId}")
    public ResultTo pdf(@PathVariable String applicationId, HttpServletResponse response) {
        try {
            ServletOutputStream outputStream = response.getOutputStream();
            applicationService.createApplicationPDF(applicationId, outputStream);
            response.setHeader("Content-disposition", "attachment; filename="
                    + URLEncoder.encode("进件详情", "UTF-8") + ".pdf");
            response.setContentType("application/pdf");
            response.setCharacterEncoding("UTF-8");
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ResultTo();
    }

    /**
     * 产品规则验证
     *
     * @param applicationVo 申请信息
     * @return 结果
     */
    @GetMapping("/verifyProductRule")
    public ResultTo verifyProductRule(ApplicationVo applicationVo) {
        applicationVo.setCustomerId(ManagerKit.getCustomerId());
        CheckResult checkResult = applicationService.verifyProductRule(applicationVo);
        return checkResult.isCheckResult() ? new ResultTo() :
                new ResultTo(ResultEnum.OPERATION_FAILED, checkResult.getCheckMsg()).setData(checkResult.getData());
    }
}
